--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+<!ENTITY version SYSTEM "../version.xml">
+]>
+<part id="adapting-existing">
+ <title>Adapating existing mainstream distributions</title>
+ <chapter id="layout">
+ <title>System layout</title>
+ <para>
+ First, OSTree encourages systems to implement <ulink
+ url="http://www.freedesktop.org/wiki/Software/systemd/TheCaseForTheUsrMerge/">UsrMove</ulink>.
+ This is simply to avoid the need for more bind mounts. By
+ default OSTree's dracut hook creates a read-only bind mount over
+ <filename class='directory'>/usr</filename>; you can of course
+ generate individual bind-mounts for <filename
+ class='directory'>/bin</filename>, all the <filename
+ class='directory'>/lib</filename> variants, etc. So it is not
+ intended to be a hard requirement.
+ </para>
+
+ <para>
+ The <filename class='directory'>/sysroot</filename> directory is
+ a new OS-level directory that OSTree expects to use as a bind
+ mount target to the physical <filename
+ class='directory'>/</filename> root directory. Remember,
+ because by default the system is booted into a
+ <literal>chroot</literal> equivalent, there has to be some way
+ to refer to the actual physical root filesystem, and there is
+ precedent for this name in the initramfs context. This
+ directory must exist; for example, the OSTree tool at runtime
+ expects that <filename
+ class='directory'>/sysroot/ostree/repo</filename> refers to the
+ system repository.
+ </para>
+
+ <para>
+ Because OSTree only preserves <filename
+ class='directory'>/var</filename> across upgrades, it is very
+ strongly recommended for systems which want to preserve
+ compatibility with the <ulink
+ url="http://www.pathname.com/fhs/">Filesystem Hierarchy
+ Standard</ulink> to create the following symbolic links:
+ <itemizedlist>
+ <listitem>
+ <para>
+ <filename class='directory'>/home</filename> to <filename class='directory'>/var/home</filename>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <filename class='directory'>/opt</filename> to <filename class='directory'>/var/opt</filename>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <filename class='directory'>/usr/local</filename> to <filename class='directory'>/var/local</filename>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <filename class='directory'>/mnt</filename> to <filename class='directory'>/var/mnt</filename>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <filename class='directory'>/tmp</filename> to <filename class='directory'>/sysroot/tmp</filename>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ Furthermore, since <filename class='directory'>/var</filename>
+ is empty by default, your operating system will need to
+ dynamically create these directories at boot. A good way to do
+ this is using <command>systemd-tmpfiles</command>, if your OS
+ uses systemd. For example:
+ </para>
+
+ <programlisting>
+ <![CDATA[
+d /var/log/journal 0755 root root -
+L /var/home - - - - ../sysroot/home
+d /var/opt 0755 root root -
+d /var/srv 0755 root root -
+d /var/roothome 0700 root root -
+d /var/usrlocal 0755 root root -
+d /var/usrlocal/bin 0755 root root -
+d /var/usrlocal/etc 0755 root root -
+d /var/usrlocal/games 0755 root root -
+d /var/usrlocal/include 0755 root root -
+d /var/usrlocal/lib 0755 root root -
+d /var/usrlocal/man 0755 root root -
+d /var/usrlocal/sbin 0755 root root -
+d /var/usrlocal/share 0755 root root -
+d /var/usrlocal/src 0755 root root -
+d /var/mnt 0755 root root -
+d /run/media 0755 root root -
+ ]]>
+</programlisting>
+ </chapter>
+
+ <chapter id="booting">
+ <title>Booting and initramfs technology</title>
+ <para>
+ OSTree comes with optional dracut+systemd integration code that
+ parses the <literal>ostree=</literal> kernel command line
+ argument in the initramfs, and then sets up the read-only bind
+ mount on <filename class='directory'>/usr</filename>, a bind
+ mount on the deployment's <filename
+ class='directory'>/sysroot</filename> to the physical <filename
+ class='directory'>/</filename>, and then finally uses
+ <literal>mount(MS_MOVE)</literal> to make the deployment root appear to be the
+ root filesystem before telling systemd to switch root.
+ </para>
+
+ <para>
+ If you are not using dracut or systemd, using OSTree should still
+ be possible, but you will have to write the integration code. Patches
+ to support other initramfs technologies and init systems, if sufficiently
+ clean, will likely be accepted upstream.
+ </para>
+
+ <para>
+ A further specific note regarding <command>sysvinit</command>:
+ OSTree used to support recording device files such the
+ <filename>/dev/initctl</filename> FIFO, but no longer does.
+ It's recommended to just patch your initramfs to create this at
+ boot.
+ </para>
+ </chapter>
+
+ <chapter id="adapting-package-manager">
+ <title>Adapting existing package managers</title>
+ <para>
+ The largest endeavor is likely to be redesigning your
+ distribution's package manager to be on top of OSTree,
+ particularly if you want to keep compatibility with the "old
+ way" of installing into the physical <filename
+ class='directory'>/</filename>. This section will use examples
+ from both <command>dpkg</command> and <command>rpm</command> as
+ the author has familiarity with both; but the abstract concepts
+ should apply to most traditional package managers.
+ </para>
+
+ <para>
+ There are many levels of possible integration; initially, we
+ will describe the most naive implementation which is the
+ simplest but also the least efficient. We will assume here that
+ the admin is booted into an OSTree-enabled system, and wants to
+ add a set of packages.
+ </para>
+
+ <para>
+ Many package managers store their state in <filename
+ class='directory'>/var</filename>; but since in the OSTree model
+ that directory is shared between independent versions, the
+ package database must first be found in the per-deployment
+ <filename class='directory'>/usr</filename> directory. It
+ becomes read-only; remember, all upgrades involve constructing a
+ new filesystem tree, so your package manager will also need to
+ create a copy of its database. Most likely, if you want to
+ continue supporting non-OSTree deployments, simply have your
+ package manager fall back to the legacy <filename
+ class='directory'>/var</filename> location if the one in
+ <filename class='directory'>/usr</filename> is not found.
+ </para>
+
+ <para>
+ To install a set of new packages (without removing any existing
+ ones), enumerate the set of packages in the currently booted
+ deployment, and perform dependency resolution to compute the
+ complete set of new packages. Download and unpack these new
+ packages to a temporary directory.
+ </para>
+
+ <para>
+ Now, because we are merely installing new packages and not
+ removing anything, we can make the major optimization of reusing
+ our existing filesystem tree, and merely
+ <emphasis>layering</emphasis> the composed filesystem tree of
+ these new packages on top. A command lke this: <command>ostree
+ commit -b osname/releasename/description
+ --tree=ref=<replaceable>osname/releasenamename/description</replaceable>
+ --tree=dir=/var/tmp/newpackages.13A8D0/</command> will create a
+ new commit in the
+ <replaceable>osname/releasename/description</replaceable>
+ branch. The OSTree SHA256 checksum of all the files in
+ /var/tmp/newpackages.13A8D0/ will be computed, but we will not
+ re-checksum the present existing tree. In this layering model,
+ earlier directories will take precedence, but files in later
+ layers will silently override earlier layers.
+ </para>
+
+ <para>
+ Then to actually deploy this tree for the next boot:
+ <command>ostree admin deploy
+ <replaceable>osname/releasenamename/description</replaceable></command>
+ </para>
+
+ </chapter>
+
+</part>